package com.sky.aspect;

import com.sky.anno.TableInject;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Component
@Aspect
public class TableInjectAspect {

    @Pointcut("execution(* com.sky.mapper.*.*(..))&& @annotation(com.sky.anno.TableInject)")
    public void pt(){}

    @Before("pt()")
    public void before(JoinPoint joinPoint){
        //获取当前正在运行的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取当前正在运行的方法对象
        Method method = signature.getMethod();
        //通过方法对象获取当前方法的注解对象
        TableInject annotation = method.getAnnotation(TableInject.class);

        Object pointArg = joinPoint.getArgs()[0];
        if(pointArg==null||joinPoint.getArgs().length==0||joinPoint.getArgs().length>1){
            return;
        }

        LocalDateTime nowTime = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();

        try {
            Method setCreatTime = pointArg.getClass().getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            Method setUpdateTime = pointArg.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method setCreatUser = pointArg.getClass().getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
            Method setUpdateUser = pointArg.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

            //获取注解的参数类型
            OperationType value = annotation.value();
            switch (value){
                case INSERT:
                    setCreatTime.invoke(pointArg,nowTime);
                    setUpdateTime.invoke(pointArg,nowTime);
                    setCreatUser.invoke(pointArg,currentId);
                    setUpdateUser.invoke(pointArg,currentId);
                    break;
                case UPDATE:
                    setUpdateTime.invoke(pointArg,nowTime);
                    setUpdateUser.invoke(pointArg,currentId);
                    break;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

}
